<?php namespace App\Api\Http\ApiControllers;

use App\Application\UserService;
use App\Exceptions\Item\OrderException;
use App\Foundation\Service\WechatPayService;
use App\Models\PayLog;
use App\Repositories\Eloquent\Order\Entity\PayParams;
use App\Repositories\Item\ItemRepositoryInterface;
use App\Repositories\Order\OrderRepositoryInterface;
use Illuminate\Http\Request;
use EasyWeChat\Payment\Order;

class OrderController extends Controller
{
    /**
     * @var OrderRepositoryInterface
     */
    protected $order_repository;

    protected $user_service;

    public function __construct(
        OrderRepositoryInterface $order_repository,
        UserService $user_service
    ) {
        $this->order_repository = $order_repository;
        $this->user_service = $user_service;
    }

    public function wechat(Request $request)
    {
        $pay = $this->formatPayParams($request);
        if ($pay->money <= 0) {
            throw new OrderException(OrderException::PAY_MONEY_ERROR);
        }

        $wechat_open_id = $this->user_service->getWechatMpOpenId($pay->user_id);
        if (!$wechat_open_id) {
            throw new OrderException(OrderException::OTHER_PAY_ERROR);
        }

        $order = $this->order_repository->create($pay);
        $pay_log = new PayLog();

        $attributes = [
            'trade_type'   => Order::JSAPI,
            'body'         => $pay->item_title,
            'out_trade_no' => $order->trade_no,
            'total_fee'    => $order->money * 100, // 单位：分
            'notify_url'   => route('notify.wechat'),
            'openid'       => $wechat_open_id,
        ];

        $wechat_order = new Order($attributes);

        $wechat_mp_pay = WechatPayService::wechatMp();
        $prepay_data = $wechat_mp_pay->createPrepayOrder($wechat_order);
        $prepay_id = $prepay_data['prepay_id'];

        $config = $wechat_mp_pay->configForJSSDKPayment($prepay_id);

        //记录请求微信支付数据
        $pay_log->storeRequest($order->trade_no, compact('attributes', 'prepay_data', 'config'));

        return response()->json($config);
    }

    private function formatPayParams(Request $request)
    {
        $item_id = $request->get('item_id');
        $item = app(ItemRepositoryInterface::class)->showWitThrow($item_id);

        if (!$item->isValid()) {
            throw new OrderException(OrderException::ITEM_INVALID_NOT_PAY);
        }

        $pay = new PayParams();
        $pay->user_id = access()->id();
        $pay->item_id = $item_id;
        $pay->item_title = $item->title;
        $pay->publisher_uid = $item->publisher_uid;
        $pay->money = $item->price;

        return $pay;
    }
}
